package top.chmin.project.cloud.builder;

import org.springframework.stereotype.Component;

/**
 * chmin
 * 2023/12/15 15:21
 * cloud-builder
 */
@Component
public class ModelBuilder implements Builder {
    @Override
    public void build(BuilderConfig config) {
        String content = """
                package top.chmin.project.cloud.#e.module#.#e.pack#.auto;
                                
                // field import auto

                import lombok.Getter;
                import lombok.Setter;
                import lombok.experimental.Accessors;
                import top.chmin.project.cloud.common.entity.*;

                /**
                 * chmin
                 * #dateTime#
                 * cloud-builder
                 */
                @Getter
                @Setter
                @Accessors(chain = true)
                public class #e.simpleName# extends Model {

                // field auto
                                
                    @Override
                    public #e.simpleName#EPC getPreCondition() {
                        return new #e.simpleName#EPC();
                    }
                    
                    public class #e.simpleName#EPC extends PreCondition {
                        private #e.simpleName#EPC() {
                        }
                    
                        private #e.simpleName#EPC(#e.simpleName#EPC parent) {
                            super(parent);
                        }
                    
                        public #e.simpleName#EPC forUpdate() {
                            addUpdateSql("update_time = ?", updateTime);
                            addUpdateSql("update_by = ?", updateBy);
                // field update auto
                            type = "UPDATE";
                            return this;
                        }
                    
                        public #e.simpleName#EPC forDelete() {
                            type = "DELETE";
                            return this;
                        }
                         
                        public #e.simpleName#EPC forCount() {
                            type = "COUNT";
                            return this;
                        }
                    
                        public #e.simpleName#EPC sub() {
                            return new #e.simpleName#EPC(this);
                        }
                    
                        public #e.simpleName#EPC complete(boolean and){
                            finish(and);
                            return parent == null ? this : (#e.simpleName#EPC)parent;
                        }
                    
                        public #e.simpleName#FPC toFlex() {
                            #e.simpleName#FPC flex = new #e.simpleName#FPC();
                            flex.setUpdateSqlList(updateSqlList);
                            flex.setUpdateValueList(updateValueList);
                            flex.setSqlList(sqlList);
                            flex.setValueList(valueList);
                            flex.setType(type);
                            return flex;
                        }
                    
                        public Condition toCondition() {
                            return toCondition(#e.simpleName#.class, "#e.tableName#");
                        }
                    
                // field epc auto
                    }
                }
                """;

        save(config, config.getEntity().getClassName(), content, true);

        config.getEntityColumnList()
                .forEach(f -> appendJava(config, f,
                        "// field import auto",
                        "import top.chmin.project.cloud.common.entity.#f.simpleType#EPCField;",
                        "import top.chmin.project.cloud.common.entity.#f.simpleType#EPCField;",
                        config.getEntity().getClassName()));

        config.getEntityColumnList()
                .stream()
                .filter(f -> !"id".equals(f.getFieldName()))
                .filter(f -> !"createBy".equals(f.getFieldName()))
                .filter(f -> !"updateBy".equals(f.getFieldName()))
                .filter(f -> !"createTime".equals(f.getFieldName()))
                .filter(f -> !"updateTime".equals(f.getFieldName()))
                .filter(f -> !f.getFullType().startsWith("java.lang."))
                .forEach(f -> appendJava(config, f,
                        "// field import auto",
                        "import #f.fullType#;",
                        "import #f.fullType#;",
                        config.getEntity().getClassName()));

        config.getEntityColumnList()
                .stream()
                .filter(f -> !"id".equals(f.getFieldName()))
                .filter(f -> !"createBy".equals(f.getFieldName()))
                .filter(f -> !"updateBy".equals(f.getFieldName()))
                .filter(f -> !"createTime".equals(f.getFieldName()))
                .filter(f -> !"updateTime".equals(f.getFieldName()))
                .forEach(f -> appendJava(config, f,
                        "// field auto",
                        "private #f.simpleType# #f.fieldName#;",
                        "    // #f.remark#\n    private #f.simpleType# #f.fieldName#;",
                        config.getEntity().getClassName()));

        config.getEntityColumnList()
                .stream()
                .filter(f -> !"id".equals(f.getFieldName()))
                .filter(f -> !"createBy".equals(f.getFieldName()))
                .filter(f -> !"updateBy".equals(f.getFieldName()))
                .filter(f -> !"createTime".equals(f.getFieldName()))
                .filter(f -> !"updateTime".equals(f.getFieldName()))
                .forEach(f -> appendJava(config, f, "// field update auto", "        addUpdateSql(\"#f.columnName# = ?\", #f.fieldName#());",
                        "        addUpdateSql(\"#f.columnName# = ?\", #f.fieldName#);", config.getEntity().getClassName()));

        config.getEntityColumnList()
                .forEach(f -> appendJava(config, f, "// field epc auto", "public #f.methodName# #f.fieldName#()",
                        """
                                        public #f.methodName# #f.fieldName#() {
                                            return new #f.methodName#();
                                        }

                                        public class #f.methodName# extends #f.simpleType#EPCField<#e.simpleName#EPC> {
                                            private #f.methodName#() {
                                                super(#e.simpleName#EPC.this, "#f.columnName#", #f.fieldName#);
                                            }
                                \t\t}""", config.getEntity().getClassName()));
    }
}
